
import java.util.*;
class CardComparator implements Comparator<Card> {
    @Override
    public int compare(Card o1, Card o2) {
        return o1.rank - o2.rank;
    }
}
    public class CardDemo {
        //1、买牌
        public static final String[] Suit = {"红桃", "方片", "梅花", "黑桃"};

        public static List<Card> buyCard() {
            List<Card> deck = new ArrayList<>(52);
            for (int i = 0; i < 4; i++) {
                for (int j = 1; j <= 13; j++) {
                    deck.add(new Card(Suit[i], j));
                }
            }
            return deck;
        }

        //2、洗牌
        private static void swap(List<Card> deck, int index1, int index2) {
            Card tmp = deck.get(index1);
            deck.set(index1, deck.get(index2));
            deck.set(index2, tmp);
        }

        public static void shuffle(List<Card> deck) {
            Random random = new Random(20240202);
            for (int i = deck.size() - 1; i > 0; i--) {
                int r = random.nextInt(i);
                swap(deck, i, r);
            }
        }

        //确保合法下标
        public static boolean checkPos(int index) {
            return index >= 0 && index <= 51;
        }

        public static void ensureIndex(int index1, int index2, int index3)
                throws IllegalIndexException {
            if (index1 == index2 || index2 == index3 || index1 == index3) {
                throw new IllegalIndexException("输入了重复下标，请重新输入！");
            }
            if (!checkPos(index1) || !checkPos(index2) || !checkPos(index3)) {
                throw new IllegalIndexException("输入下标不在合理范围内，请重新输入！");
            }
        }

        //玩家选牌
        public static List<Card> playerAcquireCards(List<Card> deck, int index1, int index2, int index3) {
            List<Card> playerList = new ArrayList<>();
            playerList.add(deck.get(index1));
            deck.set(index1, null);
            playerList.add(deck.get(index2));
            deck.set(index2, null);
            playerList.add(deck.get(index3));
            deck.set(index3, null);
            return playerList;
        }

        //电脑发牌
        public static List<Card> computerAcquireCards(List<Card> deck) {
            List<Card> computerList = new ArrayList<>();
            for (int i = 0; i < 3; i++) {
                Random random = new Random();
                int r = random.nextInt(1, 40);
                while (deck.get(r) == null) {
                    r++;
                }
                computerList.add(deck.get(r));
                deck.set(r, null);
            }
            return computerList;
        }

        //卡牌排序
        public static List<Card> sort(List<Card> list) {
            CardComparator comparator = new CardComparator();
            for (int i = 0; i < list.size() - 1; i++) {
                for (int j = 0; j < list.size() - 1 - i; j++) {
                    if (comparator.compare(list.get(j), list.get(j + 1)) > 0) {
                        swap(list, j, j + 1);
                    }
                }
            }
            return list;
        }
        public static int max(int a,int b,int c) {
            return Math.max(Math.max(a,b),Math.max(a,c));
        }
        public static String judgeWinner(List<Card> playerList,List<Card> dickList,List<Card> pussyList) {
            String winnerName = null;
            int cardsRank = 0;
            //存储对应牌型的值
            HashMap<String,Integer> scoreMap = new HashMap<>();
            scoreMap.put("豹子",6);scoreMap.put("顺金",5);scoreMap.put("金花",4);
            scoreMap.put("顺子",3);scoreMap.put("对子",2);scoreMap.put("单张",1);
            scoreMap.put("豹子杀手",0);
            //接收牌型、计算点数
            String playerCardsType = judgeCardsType(playerList);
            int playerScore = scoreMap.get(playerCardsType);
            String dickCardsType = judgeCardsType(dickList);
            int dickScore = scoreMap.get(dickCardsType);
            String pussyCardsType = judgeCardsType(pussyList);
            int pussyScore = scoreMap.get(pussyCardsType);
            int ret = judgeCardsRank(playerList,dickList,pussyList);
            //判断赢家
            switch (hasEqual(playerScore,dickScore,pussyScore)) {
                case 0:
                    if(hasZeroValue(playerScore,dickScore,pussyScore)) {
                        return "本局没有赢家！";
                    }else{
                        if(max(playerScore,dickScore,pussyScore) == playerScore) return "您是本局游戏的赢家";
                        if(max(playerScore,dickScore,pussyScore) == dickScore) return "迪克是本局游戏的赢家";
                        return "浦西是本局游戏的赢家";
                    }
                case 123:
                    if(hasZeroValue(playerScore,dickScore,pussyScore)) {
                        return "本局没有赢家！";
                    }else{
                        switch(ret) {
                            case 1:  return "您是本局游戏的赢家";
                            case 2:  return "迪克是本局游戏的赢家";
                            case 3:  return "浦西是本局游戏的赢家";
                            default: return "本局没有赢家！";
                        }
                    }
                case 12:
                    if(hasZeroValue(playerScore,dickScore,pussyScore)) {
                       if(playerScore == 0 && pussyScore == 6) return "本局没有赢家！";
                       if(playerScore == 0 && pussyScore != 6) return "浦西是本局游戏的赢家";
                       if(playerScore == 6) return "浦西是本局游戏的赢家";
                       if(judgeTwoCardsRank(playerList,dickList)<0) return "迪克是本局游戏的赢家";
                       else if(judgeTwoCardsRank(playerList,dickList)>0) return "您是本局游戏的赢家";
                       return "本局没有赢家！";
                    }else{
                        if(playerScore<pussyScore) return "浦西是本局游戏的赢家";
                        else{
                            if(judgeTwoCardsRank(playerList,dickList)<0) return "迪克是本局游戏的赢家";
                            else if(judgeTwoCardsRank(playerList,dickList)>0) return "您是本局游戏的赢家";
                            return "本局没有赢家！";
                        }
                    }
                case 13:
                    if(hasZeroValue(playerScore,dickScore,pussyScore)) {
                        if(playerScore == 0 && dickScore == 6) return "本局没有赢家！";
                        if(playerScore == 0 && dickScore != 6) return "迪克是本局游戏的赢家";
                        if(playerScore == 6) return "迪克是本局游戏的赢家";
                        if(judgeTwoCardsRank(playerList,pussyList)<0) return "浦西是本局游戏的赢家";
                        else if(judgeTwoCardsRank(playerList,pussyList)>0) return "您是本局游戏的赢家";
                        return "本局没有赢家！";
                    }else{
                        if(playerScore<dickScore) return "迪克是本局游戏的赢家";
                        else{
                            if(judgeTwoCardsRank(playerList,pussyList)<0) return "浦西是本局游戏的赢家";
                            else if(judgeTwoCardsRank(playerList,pussyList)>0) return "您是本局游戏的赢家";
                            return "本局没有赢家！";
                        }
                    }
                case 23:
                    if(hasZeroValue(playerScore,dickScore,pussyScore)) {
                        if(dickScore == 0 && playerScore == 6) return "本局没有赢家！";
                        if(dickScore == 0 && playerScore != 6) return "您是本局游戏的赢家";
                        if(dickScore == 6) return "您是本局游戏的赢家";
                        if(judgeTwoCardsRank(dickList,pussyList)<0) return "浦西是本局游戏的赢家";
                        else if(judgeTwoCardsRank(dickList,pussyList)>0) return "迪克是本局游戏的赢家";
                        return "本局没有赢家！";
                    }else{
                        if(dickScore<playerScore) return "您是本局游戏的赢家";
                        else{
                            if(judgeTwoCardsRank(dickList,pussyList)<0) return "浦西是本局游戏的赢家";
                            else if(judgeTwoCardsRank(dickList,pussyList)>0) return "迪克是本局游戏的赢家";
                            return "本局没有赢家！";
                        }
                    }
            }
            return null;
        }
        public static String judgeCardsType(List<Card> list) {
            int rank1 = list.get(0).rank; String suit1 = list.get(0).suit;
            int rank2 = list.get(1).rank; String suit2 = list.get(1).suit;
            int rank3 = list.get(2).rank; String suit3 = list.get(2).suit;
            if(isLeopard(rank1,rank2,rank3)) return "豹子";
            if(isSameSuit(suit1,suit2,suit3)&&isContinuousRank(rank1,rank2,rank3)) return "顺金";
            if(isSameSuit(suit1,suit2,suit3)&&!isContinuousRank(rank1,rank2,rank3)) return "金花";
            if(isDifferentSuit(suit1,suit2,suit3)&&isContinuousRank(rank1,rank2,rank3)) return "顺子";
            if(isPairs(rank1,rank2,rank3)) return "对子";
            if(isLeopardKiller(rank1,rank2,rank3,suit1,suit2,suit3)) return "豹子杀手";
            return "单张";
        }
        public static boolean hasA(int rank1) {
            return rank1 == 1;
        }
        public static boolean isSameSuit(String suit1,String suit2,String suit3) {
            return suit1.equals(suit2) && suit2.equals(suit3);
        }
        public static boolean isDifferentSuit(String suit1,String suit2,String suit3) {
            return !suit1.equals(suit2) && !suit2.equals(suit3) && !suit3.equals(suit1);
        }
        public static boolean isContinuousRank(int rank1,int rank2,int rank3) {
            if(hasA(rank1)) {
                if((rank2 == 2 && rank3 == 3)||(rank2==12 && rank3 ==13)) return true;
            }else{
                if(rank2-rank1 == 1 && rank3-rank2 == 1) return true;
            }
            return false;
        }
        public static boolean isLeopard(int rank1,int rank2,int rank3) {
            return rank1 == rank2 && rank1 == rank3;
        }
        public static boolean isPairs(int rank1,int rank2,int rank3) {
            return rank1 == rank2 || rank1 == rank3 || rank2 == rank3;
        }
        public static boolean isLeopardKiller(int rank1,int rank2,int rank3
                ,String suit1,String suit2,String suit3) {
            return isDifferentSuit(suit1,suit2,suit3) &&
                    rank1 == 2 && rank2 == 3 && rank3 == 5;
        }
        public static int hasEqual(int score1,int score2,int score3) {
            if(score1 == score2 && score2 == score3) return  123;
            if(score1 == score2) return 12;
            if(score2 == score3) return 23;
            if(score3 == score1) return 13;
            return 0;
        }
        public static boolean hasZeroValue(int score1,int score2,int score3) {
            return score1 == 0 || score2 == 0 || score3 == 0;
        }
        public static int judgeCardsRank(List<Card> list1,List<Card> list2,List<Card> list3) {
            int maxRank1 = list1.get(2).rank;
            int maxRank2 = list2.get(2).rank;
            int maxRank3 = list3.get(2).rank;
            switch(hasEqual(maxRank1,maxRank2,maxRank3)) {
                case 0:
                    if(max(maxRank1,maxRank2,maxRank3) == maxRank1) return 1;
                    if(max(maxRank1,maxRank2,maxRank3) == maxRank2) return 2;
                    return 3;
                case 123:
                    return 123;
                case 12:
                    if(max(maxRank1,maxRank2,maxRank3) == maxRank1) return 12;
                    return 3;
                case 13:
                    if(max(maxRank1,maxRank2,maxRank3) == maxRank1) return 13;
                    return 2;
                case 23:
                    if(max(maxRank1,maxRank2,maxRank3) == maxRank2) return 23;
                    return 1;
            }
            return 0;
       }
        public static int judgeTwoCardsRank(List<Card> list1,List<Card> list2) {
            if(list1.get(2).rank<list2.get(2).rank) return -1;
            else if((list1.get(2).rank>list2.get(2).rank)) return 1;
            return 0;
        }
        //游戏开始
        public static void main(String[] args) {
            int runCode = 1;//决定是否循环进行游戏
            while (runCode != 0) {
                List<Card> deck = buyCard();
                //随机洗牌
                Random random = new Random();
                int shuffleTime = random.nextInt() % 3;
                while (shuffleTime != 0) {
                    shuffle(deck);
                    //System.out.println(deck);
                    shuffleTime--;
                }
                System.out.println("卡牌下标为0-51，请输入三个不同的卡牌下标进行选牌");
                Scanner scanner = new Scanner(System.in);
                int index1, index2, index3;
                try {
                    index1 = scanner.nextInt();
                    index2 = scanner.nextInt();
                    index3 = scanner.nextInt();
                    ensureIndex(index1, index2, index3);
                    //玩家选牌
                    List<Card> playerList = playerAcquireCards(deck, index1, index2, index3);
                    System.out.println("您的牌是 " + sort(playerList)+" 牌型是: " +judgeCardsType(playerList));
                    //电脑选牌
                    List<Card> computerList1 = computerAcquireCards(deck);
                    List<Card> computerList2 = computerAcquireCards(deck);
                    //揭牌
                    System.out.println("迪克的牌是 " + sort(computerList1)+" 牌型是: "+judgeCardsType(computerList1));
                    System.out.println("浦西的牌是 " + sort(computerList2)+" 牌型是: "+judgeCardsType(computerList2));
                    //比较大小
                    String winnerName = judgeWinner(playerList,computerList1,computerList2);
                    System.out.println(winnerName);


                } catch (InputMismatchException e) {
                    System.out.println("输入的下标不是整数，请重新输入！");
                    continue;
                } catch (IllegalIndexException e) {
                    e.printStackTrace();
                    continue;
                }
                System.out.println("您是否想继续玩：继续请输入1，结束请输入0");
                runCode = scanner.nextInt();
            }
            System.out.println("感谢游玩！");
        }
    }
